#include <iostream>
#include <unistd.h>
#include <signal.h>

//本程序用于观察信号屏蔽对pending表的影响

//打印未决信号集
void PrintPending(sigset_t& pending)
{
    int cnt = 1;
    for(int signo = 31; signo >= 1; signo--)
    {
        if(cnt == 8)
        {
            std::cout << ' ';
            cnt = 0;
        }
        if(sigismember(&pending, signo)) std::cout << '1';
        else std::cout << '0';
        cnt++;
    }
    std::cout << std::endl;
}

//自定义捕捉
void handler(int sig)
{
    std::cout << sig << "号信号递达" << std::endl;

    //查看解除屏蔽后，pending是在处理结束前清理还是结束后清理
    std::cout << "******* ******** ******** ********" << std::endl;
    sigset_t pending;
    sigpending(&pending);
    PrintPending(pending);
    std::cout << "******* ******** ******** ********" << std::endl;
}

int main()
{
    // 1. 屏蔽2号信号SIGINT
    sigset_t set, oldset;
    sigemptyset(&set);
    sigemptyset(&oldset);

    sigaddset(&set, SIGINT);

    sigprocmask(SIG_SETMASK, &set, &oldset);

    // 5. 为了观察结果，对2号信号进行自定义捕捉
    signal(SIGINT, handler);

    int cnt = 0;
    while(true)
    {
        // 2. 获取当前进程的未决信号集
        sigset_t pending;
        sigpending(&pending);

        // 3. 打印
        PrintPending(pending);

        sleep(1);
        cnt++;

        // 4. 10秒后，解除2号信号的屏蔽
        if(cnt == 10)
        {
            std::cout << "解除2号信号的屏蔽" << std::endl;
            sigprocmask(SIG_SETMASK, &oldset, nullptr);
        }
    }
    return 0;
}